import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';
import { BusinessException } from '../exceptions/business.exception';

@Injectable()
export class CustomValidationPipe implements PipeTransform {
  async transform(value: any, metadata: ArgumentMetadata): Promise<any> {
    const { metatype } = metadata;
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }

    const errors = await validate(plainToInstance(metatype, value), {
      whitelist: true, // 自动去除未定义字段
      forbidNonWhitelisted: false, // 遇到未定义字段抛错（可选）
      skipMissingProperties: false,
      skipNullProperties: false,
      skipUndefinedProperties: false,
    });

    if (errors.length > 0) {
      const messages = errors
        .map((err) => Object.values(err.constraints || {}))
        .flat();
      throw new BusinessException(messages.join(','));
    }

    return value;
  }

  private toValidate(metatype: any): boolean {
    const types: any[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
